package com.yfbao.horizon.schedule.tk.service;

import io.lettuce.core.AbstractRedisClient;
import javafx.scene.Parent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisClusterConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePool;
import org.springframework.stereotype.Service;
import redis.clients.jedis.*;

import java.lang.reflect.Field;
import java.util.Map;

@Slf4j
@Service
public class RedisConnectionPoolService {


//    @Autowired
//    private JedisPool jedisPool;
    @Autowired
    private  RedisConnectionFactory redisConnectionFactory;

//    @Autowired
//    public RedisConnectionPoolService(RedisConnectionFactory redisConnectionFactory) {
//
//    }


    public void getRedisPoolStatus(){
//        int activeConnections = jedisPool.getNumActive();  // 当前活跃连接数
//        int idleConnections = jedisPool.getNumIdle();      // 当前空闲连接数
//        int waitingConnections = jedisPool.getNumWaiters(); // 当前等待连接数
//
//        String format = String.format("Active connections: %d, Idle connections: %d, Waiting connections: %d",
//                activeConnections, idleConnections, waitingConnections);
//        log.info(format);
    }

    public void showConnectionPoolInfo() {
        // 获取连接池信息（假设使用 LettuceConnectionFactory）
        if (redisConnectionFactory instanceof LettuceConnectionFactory) {
            LettuceConnectionFactory lettuceFactory = (LettuceConnectionFactory) redisConnectionFactory;
            // 获取连接池指标信息
            log.info("redis factory type:lettuceFactory");
//            lettuceFactory.getNativeClient()
//            LettucePool pool = lettuceFactory.getNativeConnection().pool();
//            System.out.println("Max active connections: " + pool.getMaxActive());
//            System.out.println("Number of idle connections: " + pool.getNumIdle());
        }

        if (redisConnectionFactory instanceof JedisConnectionFactory) {
            JedisConnectionFactory  jedisConnectionFactory = (JedisConnectionFactory ) redisConnectionFactory;
            log.info("redis factory type:jedisFactory");
            // 获取连接池指标信息

            String jedisRunType = getJedisRunType(jedisConnectionFactory);
            log.info("redis mode:"+jedisRunType);

            try {

                if (jedisRunType.equals("Cluster")) {
                    Field jedisClusterField = JedisConnectionFactory.class.getDeclaredField("cluster");
                    jedisClusterField.setAccessible(true);
                    JedisCluster jedisCluster = (JedisCluster) jedisClusterField.get(jedisConnectionFactory);
                    Map<String, JedisPool> clusterNodes = getJedisClusterNodes(jedisCluster);
                    if (clusterNodes != null) {
                        for (Map.Entry<String, JedisPool> entry : clusterNodes.entrySet()) {
                            JedisPool pool = entry.getValue();
                            String name= entry.getKey();
//                            meterRegistry.gauge("redis.cpool.active:"+name, pool, JedisPool::getNumActive);
//                            meterRegistry.gauge("redis.cpool.idle:"+name, pool, JedisPool::getNumIdle);
//                            meterRegistry.gauge("redis.cpool.waiting:"+name, pool, JedisPool::getNumWaiters);
                            log.info("redis.cluster:{}, active:{},idle:{},waiting:{}",name,pool.getNumActive(),pool.getNumIdle(),pool.getNumWaiters());
                        }
                    }else {
                        log.warn("redis.cluster: get error");
                    }
                } else if (jedisRunType.equals("Sentinel")) {
                    Field sentinelPoolField = JedisConnectionFactory.class.getDeclaredField("pool");
                    sentinelPoolField.setAccessible(true);
                    JedisSentinelPool sentinelPool = (JedisSentinelPool) sentinelPoolField.get(jedisConnectionFactory);

//                    meterRegistry.gauge("redis.sPool.active", sentinelPool, JedisSentinelPool::getNumActive);
//                    meterRegistry.gauge("redis.sPool.idle", sentinelPool, JedisSentinelPool::getNumIdle);
//                    meterRegistry.gauge("redis.sPool.waiting", sentinelPool, JedisSentinelPool::getNumWaiters);
                    log.info("redis.sentinelPool, active:{},idle:{},waiting:{}",sentinelPool.getNumActive(),sentinelPool.getNumIdle(),sentinelPool.getNumWaiters());
                } else {
                    Field jedisPoolField = JedisConnectionFactory.class.getDeclaredField("pool");
                    jedisPoolField.setAccessible(true);
                    JedisPool jedisPool = (JedisPool) jedisPoolField.get(jedisConnectionFactory);
//                    meterRegistry.gauge("redis.pool.active", jedisPool, JedisPool::getNumActive);
//                    meterRegistry.gauge("redis.pool.idle", jedisPool, JedisPool::getNumIdle);
//                    meterRegistry.gauge("redis.pool.waiting", jedisPool, JedisPool::getNumWaiters);
                    log.info("redis.pool, active:{},idle:{},waiting:{}",jedisPool.getNumActive(),jedisPool.getNumIdle(),jedisPool.getNumWaiters());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }

    }

    private String getJedisRunType(JedisConnectionFactory  jedisConnectionFactory){
        try {
            RedisClusterConnection clusterConnection = jedisConnectionFactory.getClusterConnection();
            if (clusterConnection != null) {
                return "Cluster";
            }
        }catch (Exception e){
        }

        try{
            RedisSentinelConnection sentinelConnection = jedisConnectionFactory.getSentinelConnection();
            if (sentinelConnection != null) {
                return "Sentinel";
            }
        }catch (Exception e){
        }

        return "Standalone";
    }

    // 通过反射获取所有的 JedisPool
    public Map<String, JedisPool> getJedisClusterNodes(JedisCluster jedisCluster ){
        // 获取 JedisCluster 中的 connectionHandler 字段
        try {
            Class<?> superclass = jedisCluster.getClass().getSuperclass();
            Field connectionHandlerField = superclass.getDeclaredField("connectionHandler");
            connectionHandlerField.setAccessible(true);
            JedisClusterConnectionHandler connectionHandler = (JedisClusterConnectionHandler) connectionHandlerField.get(jedisCluster);

            // 获取 JedisSlotBasedConnectionHandler 中的 cache 字段
            if (connectionHandler instanceof JedisSlotBasedConnectionHandler) {
                Class<?> superclass1 = connectionHandler.getClass().getSuperclass();
                Field cacheField = superclass1.getDeclaredField("cache");
                cacheField.setAccessible(true);
                JedisClusterInfoCache JedisClusterInfo = (JedisClusterInfoCache) cacheField.get(connectionHandler);
                Map<String, JedisPool> nodes = JedisClusterInfo.getNodes();
                return nodes;
            }
        }catch (Exception e){
            log.error("redis cluster get error",e);
        }
        return null;
    }
}
